﻿using System;
using System.Collections.Generic;
using NUnit.Framework;
using System.Linq;

namespace TooManyNamespaces.Fluent.Utilities.Test
{
    [TestFixture]
    public class Extensions
    {
        [TestCase]
        public void TestEach()
        {
            int fCount = 0;
            int tCount = 0;

            bool[] list = { true, false, true, false, false, true };

            list.Each(x => { if (x) tCount++; else fCount++; });
            Assert.True(tCount == 3);
            Assert.True(fCount == 3);
        }

        private struct TestStruct
        {
            public string Foo;
            public string Bar;

            public static TestStruct Create(string foo, string bar)
            {
                var item = new TestStruct();
                item.Foo = foo;
                item.Bar = bar;
                return item;
            }
        }

        [TestCase]
        public void TestContains()
        {

            TestStruct[] list = { TestStruct.Create("hello", "world"), TestStruct.Create("bar", "foo")};

            var item = TestStruct.Create("bar", "foo");

            Assert.That(list.Contains(item, (a, b) => a.Foo == b.Foo));
        }

        [TestCase]
        public void TestDistinct()
        {

            TestStruct[] list = 
            { 
                TestStruct.Create("hello", "world"), 
                TestStruct.Create("bar", "foo"), 
                TestStruct.Create("bar", "foo"), 
                TestStruct.Create("bar", "foo"), 
                TestStruct.Create("bar", "bar") };

            var dList = list.Distinct((a, b) => a.Foo == b.Foo && a.Bar == b.Bar);

            Assert.That(dList.Count() == 3);
            dList = list.Distinct((a, b) => a.Foo == b.Foo);

            Assert.That(dList.Count() == 2);
        }

        private class TestClass { }

        [TestCase]
        public void TestIsReferenceNull()
        {
            var obj = new TestClass();
            Assert.False(obj.IsReferenceNull());
            obj = null;
            Assert.True(obj.IsReferenceNull());

            //make sure this works for interfaces
            IEnumerable<string> list = new string[]{ "hello", "world" };
            Assert.False(list.IsReferenceNull());
            list = null;
            Assert.True(list.IsReferenceNull());
        }

        [TestCase]
        public void TestReferenceEquals()
        {
            var item = new TestClass();
            var list = new List<TestClass>() { item };

            Assert.That(item.ReferenceEquals(list[0]));
        }

        [TestCase]
        public void TestContainsReference()
        {
            var item = new TestClass();
            var list = new List<TestClass>() { new TestClass(), new TestClass(), new TestClass(), item };

            Assert.That(list.ContainsReference(item));

            var newItem = new TestClass();
            Assert.False(list.ContainsReference(newItem));
        }

        [TestCase]
        public void TestIfTrue()
        {
            bool condition = true;
            bool result = false;
            condition.IsTrue(() => result = true);
            Assert.True(result);
        }

        [TestCase]
        public void TestIfFalse()
        {
            bool condition = false;
            bool result = false;
            condition.IsFalse(() => result = true);
            Assert.True(result);
        }
    }
}
